package com.health.redis;

 
	import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Transaction;

import com.health.mapp.service.Adapter;

	/**
	 *  redis 操作api
	 * <一句话功能简述>
	 * <功能详细描述>
	 * 
	 * @author  khj
	 * @see  [相关类/方法]
	 * @since  [产品/模块版本]
	 */
	public class RedisClient 
	{
		private static Logger logger = Logger.getLogger(Adapter.class);
	 
		static long  pipelineCount=0;
		public static boolean getJedisIsConnected()
		{
			
			return RedisClientPool.jedisIsConnected;
		}
	    /**
	     *  保存数据   类型为 Map
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @param mapData
	     * @see [类、类#方法、类#成员]
	     */
	    public static void setMapDataToRedis(String flag,Map<String,String> mapData)
	    {       
	        Jedis redisClient = null;
	         
	            redisClient = RedisClientPool.jedisPool.getResource();
	            redisClient.hmset(flag,mapData);
	         
	        
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	         
	    }
	    
	    /**
	     *  保存数据   类型为 key-value
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @param field
	     * @param value
	     * @see [类、类#方法、类#成员]
	     */
	    public static void setDataToRedis(String flag,String field,String value)
	    {
	        Jedis redisClient = null;
	        
	            redisClient = RedisClientPool.jedisPool.getResource();
	            redisClient.hset(flag, field, value);
	        // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	         
	    }
	    /**
	     *  保存数据   类型为 栈 key-value
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @param field
	     * @param value
	     * @see [类、类#方法、类#成员]
	     */
	    public static void lpushDataToRedis(String field,String value)
	    {
	           Jedis redisClient = null;
	         
	            redisClient = RedisClientPool.jedisPool.getResource();
	            redisClient.lpush(field, value);
	         
	        
	        
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	        
	    }
	    /**
	     *  获取Map数据
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @return
	     * @see [类、类#方法、类#成员]
	     */
	    public static Map<String,String> getMapData(String flag)
	    {
	        Map<String,String> dataMap = null;
	        
	        Jedis redisClient = null;
	        
	            redisClient = RedisClientPool.jedisPool.getResource();
	            dataMap = redisClient.hgetAll(flag);
	        
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	         
	        return dataMap;
	    }
	    
	    public static long deleteData(String flag)
	    {
	        long result = 0;
	        Jedis redisClient = null;
	        
	            redisClient = RedisClientPool.jedisPool.getResource();
	            result = redisClient.del(flag);
	         
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	      
	        
	        return result;
	    }
	    
	    /**
	     * 根据key和字段获取数据 
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @param field
	     * @return
	     * @see [类、类#方法、类#成员]
	     */
	    public static String getData(String flag,String field)
	    {
	        String data = null;
	        Jedis redisClient = null;
	        
	            redisClient = RedisClientPool.jedisPool.getResource();
	            data = redisClient.hget(flag, field);
	       
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	        
	        
	        return data;
	    }

	    /**
	     * 根据key获取数据 前1000个数据
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @param field
	     * @return
	     * @see [类、类#方法、类#成员]
	     */
	    public static List lRangData(String flag)
	    {
	    	List data = null;
	        Jedis redisClient = null;
	        
	            redisClient = RedisClientPool.jedisPool.getResource();
	            data = redisClient.lrange(flag, 0, 1000);
	       
	         
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	        
	        
	        return data;
	    }
	    
	    
	    public static List zAddData(String key,double score,String member)
	    {
	    	List data = null;
	        Jedis redisClient = null;
	        
	            redisClient = RedisClientPool.jedisPool.getResource();
	            redisClient.zadd(key, score, member);
	        
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	        
	        
	        return data;
	    }
	    
	    public static void sortedSet(String zaddKey,String hsetKey,String zaddValue ,  double score,   String content)
	    {

			
			    Jedis redisClient = null;
		        	  	//System.out.println("gap:"+(a2-a1));
		                redisClient = RedisClientPool.jedisPool.getResource();
						// 初始化CommentId索引 SortSet
		            	redisClient.zadd(zaddKey, score,  zaddValue);
		              	 
		            	//long zcount=redisClient.zcount(zaddKey, 0, 100);
				    	//System.out.println("sortSetKey:"+zcount);
						// 初始化Comment数据 Hash
		            	redisClient.hset(hsetKey,zaddValue, content);
		            	
		       
		         
		            // 还原到连接池
		           RedisClientPool.jedisPool.returnResource(redisClient);
		             
		       
		        
			
		
	    }
		public static void sortedSetPagenation(String sortSetKey,String dataKey,String min,String max, int offset, int count){
			
			 Jedis redisClient = null;
			     redisClient = RedisClientPool.jedisPool.getResource();
		    
					// 倒序取 从0条开始取 5条 Id 数据
		            //key, min, max, offset, count
		           // long result=redisClient.zcount(sortSetKey, min, max);
		    		//System.out.println("result:"+result);
					LinkedHashSet<String> sets = (LinkedHashSet<String>) redisClient.zrevrangeByScore(sortSetKey, min, max, offset, count);
					String[] items = new String[]{};
					logger.debug("LinkedHashSet:"+sets.toString());
					// 根据id取comment数据
					if(sets.size()>0)
					{
						List<String> list = redisClient.hmget(dataKey, sets.toArray(items));
				   
						for(String str : list){
							logger.debug(str);
				 
						}
						
					}
					
				 
		         
		       
		        	 
		            // 还原到连接池
		             RedisClientPool.jedisPool.returnResource(redisClient);
		       
			
		}
		/**
	     *  保存数据   类型为 栈 key-value
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @param field
	     * @param value
	     * @see [类、类#方法、类#成员]
	     */
	    public static void lpushDataToRedisByPipeline(String field,String value)
	    {
	        Jedis redisClient = null;
	         
	            redisClient = RedisClientPool.jedisPool.getResource();
	            Pipeline pl = redisClient.pipelined();
	            
	            pl.lpush(field, value);
	            pipelineCount++;
	            if(pipelineCount==500)
	            {
	            	  pl.sync();
	            }
	          
	        
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	         
	    }
	    
	    /**
	     *  保存数据   类型为 栈 key-value
	     * <一句话功能简述>
	     * <功能详细描述>
	     * @param flag
	     * @param field
	     * @param value
	     * @see [类、类#方法、类#成员]
	     */
	    public static Object rpopDataOutRedis(String field)
	    {    Object data =null;
	        Jedis redisClient = null;
	        
	            redisClient = RedisClientPool.jedisPool.getResource();
	           
	             
	            data=redisClient.rpop(field);
	             
	          
	       
	         
	            // 还原到连接池
	            RedisClientPool.jedisPool.returnResource(redisClient);
	         
	        return data;
	        
	    }
	    
	    
	    public static void main(String[] args)  throws Exception
	    {         
	      //  RedisClient.testMap();  
	  
	        
 
	    	 
	        for  ( int  i =  1 ; i <=  100 ; i+=10) {    

       	       long score=System.currentTimeMillis();
       	  
	           RedisClient.sortedSet("order:userId:"+5 ,"order:orderId:" , "orderId:"+i,score, "comment content ......."+i);
	          
	          }    
	          RedisClient.sortedSetPagenation("order:userId:"+5,"order:orderId:", "9999999999999","0",3,4);
	          RedisClient.updateSortedSetPagenation("order:userId:"+5, "order:userId:"+5); 
	          RedisClient.sortedSetPagenation("order:userId:"+5,"order:orderId:", "9999999999999","0",3,4);
	        //for  ( int  i =  1 ; i <=  100 ; i+=10) {    

	        	//System.out.println(""+RedisClient.visiterIPLimit("135.32.6.245",8));
	        //}
	        
	        
	    }  
	    /**
		   * 
		   * @param zAddKey
		   * @param hSetKey
		   * @param zAddValue
		   * @param score
		   * @param content
		   * @param groupNo
		   */
		  public static  void updateSortedSetPagenation(final String zAddKey,final String hSetKey )
		  {
	 
			  Jedis redisClient = null;
				 
		            
		            redisClient = RedisClientPool.jedisPool.getResource();
		    
			        	 
		            Long result1 = redisClient.del(zAddKey);  
                    Long result2 = redisClient.del(hSetKey);    
			            
		        
		        	 
		        	 
		            // 还原到连接池
		             RedisClientPool.jedisPool.returnResource(redisClient);
		         
			
			 	
			
		    }
		 
		  /**
		   * 从列表中从头部开始移除count个匹配的值。如果count为零，所有匹配的元素都被删除。如果count是负数，内容从尾部开始删除。 
		   * @param zAddKey
		   * @param hSetKey
		   * @param zAddValue
		   * @param score
		   * @param content
		   * @param groupNo
		   */
		  public static  void deleteSortedSetPagenation(final String zAddKey,final String hSetKey )
		  {
			  Jedis redisClient = null;
				 
		          
		                redisClient = RedisClientPool.jedisPool.getResource();
		    
			        	
	 
			        	//connection.zAdd(  zAddKey.getBytes(), score,  zAddValue.getBytes());
			        	//connection.hSet(hSetKey.getBytes(),zAddValue.getBytes(), Byte2ObjectUtil.objectToByte(content));
	                    Long result1 = redisClient.del(zAddKey);  
	                    Long result2 = redisClient.del(hSetKey);     
			              
			            
		      
		         
		        	 
		            // 还原到连接池
		             RedisClientPool.jedisPool.returnResource(redisClient);
		         
			 	
			
		    }
	    public static boolean visiterIPLimit(String IP,long IPLimit)
	    {

			
			    Jedis redisClient = null;
			 
		         
		           redisClient = RedisClientPool.jedisPool.getResource();
		    
		           //IP是否已存在
		           boolean   isKeyExists =  redisClient.exists("rate.limiting:"+IP);
					  
		           if (isKeyExists ==true)
		           {
		        	   //存在则判断现在已经访问多少次了
		        	   long times = redisClient.incr("rate.limiting:"+IP);
		           
		        	   if (times > IPLimit)
		        	   {
		                
		        		   logger.error(" 访问频率超过了限制，请稍后再试");
		        		   return false;
		        
		        	   }
		           }
		          else{
		               // MULTI
		        	   Transaction tx =  redisClient.multi();
		        	   tx.incr("rate.limiting:"+IP);
		        	   tx.expire ("rate.limiting:"+IP, 10); //这个用事务控制，否则这行如果没有执行，那用户最多只能访问100次博客了
		               //EXEC
		               tx.exec();
		              
		           }
		       
		        
		        	 
		            // 还原到连接池
		             RedisClientPool.jedisPool.returnResource(redisClient);
		         
		        
			return true;
		
	    }
	    
	    
	    
	    public void testList()
	    {  
	        Jedis redis = RedisClientPool.jedisPool.getResource();
	        //hset key field value将哈希表key中的域field的值设为value。 
	        redis.hset("table", "field1", "value1"); 
	        redis.hset("table", "field2", "value2"); 
	        redis.hset("table", "field3", "value3"); 
	        //返回哈希表key中，一个或多个给定域的值。 
	        List<String> list = redis.hmget("table","field1","field2","field3"); 
	        for(String tmp : list)
	        { 
	            System.out.println(tmp); 
	        } 
	    }
	    
	    public static void testMap()
	    {
	        //同时将多个field - value(域-值)对设置到哈希表key中。 
	        Map<String,String> map = new ConcurrentHashMap<String,String>();
	        for (int i = 0;i < 10000;i++)
	        {
	            map.put("field"+i, "value"+i); 
	        }
	        if (null != getData("table", "field1"))
	        {
	            deleteData("table");
	        }
	        //得到map下面的username的值 
	        Map<String,String> maps = getMapData("table");
	        System.out.println(maps.size());
	        
	        setMapDataToRedis("table",map);

	        //HGETALL key返回哈希表key中，所有的域和值。 
	        maps = getMapData("table"); 
	       
	        System.out.println(maps.size());
	    }

	}

 